as_snipercaptcha: Pure CSS/DHTML (no GD) CAPTCHA engine class

as_snipercaptcha.php contains a PHP class (CSniperCaptcha) for well known CAPTCHA task - protecting interactive WEB sites from SPAM bot attacks.
Unlike majority of CAPTCHA engines, this class does not use graphics libraries and does not create distorted alpha-numeric images to recognize (there're already handreds of a such classes).
The main idea is simple : user doesn't enter generated digits into a text INPUT field, instead he (she) points and clicks color-marked cells in the CAPTCHA grid, and his browser sends results to the server through AJAX calls and receives commands for the next click, until all checking sequence is done. Testing results return into the client after the last click. So Your JavaScript code can do some nesessary job in case of passed (or failed) CAPTCHA test.

Here is an installation and using instruction for as_snipercaptcha class.

Installing as_snipercaptcha

  1. Download distributive zip file and unzip it into temporary folder. If you will use CAPTCHA engine from more than one page, place as_snipercaptcha.php file into one of folders listed in your PHP.ini "include_path" variable. Otherwise, just place it in the folder with your main script.
    If You use jQuery framework in Your project, it's recommended to use jQuery-aware class version - as_snipercaptcha_j.php, so there is no need to include as_jsfunclib.js in that case. JQuery version of a class is more compact and might be more cross-browser compatible.
  2. Move or copy image files (*.png,*.gif) from distributive to Your Image folder, or into the folder where Your PHP pages resides. (You'll need to set relative path to this folder in the defined IMGPATH constant if it's not a current dir)
    define('IMGPATH','allimages/');
    File captchasight.png is a "marker" that CSniperCaptcha uses to point a cell. cap_progress.png is used to show a progress bar of a testing process.
  3. Make sure that as_jsfunclib.js file located in the current directory, or place it into Your "javascript" repository folder (in that case You'll need to pass it in DrawRefs() method).
    This javascript function set is used to make XmlHttpRequest object.

Using CSniperCaptcha class

CSniperCaptcha generates small HTML table (let's call it "grid") that may contain variable number of rows and columns. These dimensions can be set by You, or randomly generated by the class (if not passed). Grid cell size is also variable, that can be passed or random-generated. Random generation is recommended if You want more protect from CAPTCHA cracking algorhytms. How this works :

  1. When CAPTCHA grid is ready and rendered in the browser, AJAX request sends it's absolute position (x and y coords) to the server.
  2. Then server starts a checking sequence: it randomly chooses cell number, computes it's absolute coordinates (based on base position and dimensions of a grid), and sends them to the client in AJAX response.
  3. Client receives these coordinates and moves special image marker to the specified position.
  4. Site visitor must point marked cell with a mouse and click on it. OnClick function sends the selected grid cell "id" to the server.
  5. When all NN clicks done, server script checks matching of strings and sends 'yes' or 'no' to the client. Besides, it stores checking result in $_SESSION variable.
If You wrote Your Javascript functions for 'success' and/or 'fail' cases, they can be fired after checking. For example, You can make visible or enabled some additional FORM elements if CAPTCHA test passed, or hide them in the case of fail. All these actions will be done immediately after the last user mouse click (on CAPTCHA grid), before the user press 'submit' button.
So You can even disable 'PUBLISH' button, to prevent sending form to the server.

Here is a simple example. (CAPTCHA grid will be drawn with random dimensions and cell height/width)

require_once('as_snipercaptcha.php');

$captcha = new CSniperCaptcha();

CSniperCaptcha::DrawRefs(); // draw links to the CSS and js files used by the class
// draw the main HTML code, beginning FORM tag and
// all form fields You need (TEXTAREA etc.) without 'submit' button

$captcha->Draw();

//... Now You can draw a submit button and </FORM> ending tag

$captcha->DrawJsCode();

// the rest of Your HTML code here ...

CSniperCaptcha methods

  • CSniperCaptcha($codelen=4, $submitid='', $jscode_success='',$jscode_fail='', $reinit=false) - class constructor.


  • Parameters:
  • SetServerScript($uri) - call this method if You place CAPTCHA backend-functionality into a separated script file.


  • Parameters:
  • DrawRefs($csspath='',$jspath='') - call this method when You're ready to echo <STYLE> and <SCRIPT> tags that refers to the css file captcha_styles.css and javascript file as_jsfunclib.js, used by the class. If You insert all css styles from captcha_styles.css to Your own css that contain ALL styles used in Your site, and therefore You don't need to make a STYLE reference, just pass false as $csspath to this method. The same is true for $jspath.

    Parameters:
  • SetBufferedOutput($buffered=true) - set "buffered" mode, so from this moment all HTML code is not echoed directly to clinet stream, and all methods (Draw(), DrawJsCode(), DrawRefs()) return respective HTML code instead of echoing it. It is needed when PHP developer builds all HTML in memory, and outputs it at the end of program.

    Parameter - optional boolean or integer value. True by default. False or zero means "NON BUFFERED".
  • Draw($width=0, $height=0, $cellsize=0, $tovar=0) - this method draws HTML code of a CAPTCHA grid anf progress bar.

    Parameters:
  • DrawJsCode($autostart=1) - this method draws client-side Javascript code needed for CAPTCHA processing. You have to call it AFTER printing the grid (i.e. after Draw() call), unless You pass false in $autostart parameter.

    Parameters:

    Using example

    We want to draw CAPTCHA grid with random columns, rows and cell width/height. User must click correctly 5 times on marked cells. When checking sequence is done and user passed the test, the "SUBMIT" button will be enabled.
    Note that submit button is drawn with initial DISABLED tag.
    require_once('as_snipercaptcha.php');
    
    $captcha = new CSniperCaptcha(5, 'btn_submit'); // here SESSION is started, so NO HTML output before this !
    
    // As the same script receives the POSTed form data, We have to check if test passed, and publish data to the SQL...
    if(!empty($_POST)) {
      if($captcha->CheckPassed()){
         // process user data (publish to the database etc.
         PublishNewMessage(); // Your function that does a job
         echo "Thanks, Your message published !";
      }
      else {
         echo "You are a bot, go away";
      }
      exit;
    }
    
    // print the main HTML code, beginning FORM tag and
    // all form fields You need (TEXTAREA etc.) without 'submit' button
    echo "submit new message";
    $self = $_SERVER['PHP_SELF'];
    
    DrawRefs(); // draw links to the CSS and js files used by the class
    
    
    echo "<FORM action='$self' method='POST' name='myform'>";
    echo "<TEXTAREA name='messagetext' style='width:100%; height:120px'></TEXTAREA><br />";
    
    $captcha->Draw();
    
    echo "<input type='SUBMIT' id='btn_submit' name='btn_submit' value='Submit message' DISABLED />
    echo "</FORM>";
    $captcha->DrawJsCode();
    //... print the rest of HTML code, including ending </BODY>, </HTML> tags
    
    
    If You use AJAX (XmlHTTPRequest) to send FORM data (data will be posted to the server without whole html page redrawing), Your backend php script (that receives data from the client) must check $captcha->CheckPassed() result, and handle data only if true returned. Here is a simple backend script example:
    // backend for processing posted data
    require_once('as_snipercaptcha.php');
    $captcha = new CSniperCaptcha();
    if($captcha->CheckPassed()) {
       PublushFormData($_POST); // processing posted data function...
       echo "thanks, your message added"; // ajax response will go to the client
    }
    else echo "Error, CAPTCHA test not passed";
    
    

    Change Log

    1.03.007 (10.12.2008)
    1.03.006 (03.12.2008)
    1.02.004 (10.05.2008)
    1.02.003 (22.04.2008)
    1.01.002 (22.04.2008)
    1.0.001 (28.02.2008)


    Copyright © Alexander Selifonov, as-works.narod.ru